package com.dms.modules.statistics.controller;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.dms.common.api.ApiResponse;
import com.dms.common.security.SecurityUtils;
import com.dms.modules.product.service.ProductService;
import com.dms.modules.order.mapper.OrderMapper;
import com.dms.modules.merchant.entity.Merchant;
import com.dms.modules.product.service.ProductAnalyticsService;
import com.dms.modules.user.service.UserBehaviorService;
import com.dms.modules.product.service.ProductCommentService;
import com.dms.modules.merchant.service.MerchantStatisticsService;
import com.dms.modules.product.service.ProductRecommendationService;
import com.dms.modules.merchant.service.MerchantService;
import com.dms.modules.user.model.UserBehaviorStats;
import com.dms.modules.product.vo.CommentStatisticsVO;
import com.dms.modules.merchant.vo.MerchantSalesStatsVO;
import com.dms.modules.merchant.vo.MerchantProductStatsVO;
import com.dms.modules.merchant.vo.MerchantTodayStatsVO;
import com.dms.modules.merchant.vo.MerchantHotProductVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.Map;
import java.util.HashMap;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.stream.Collectors;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.dms.common.exception.BusinessException;
import java.time.format.DateTimeParseException;

@Slf4j
@RestController
@RequestMapping("/api/v1/statistics")
@Api(tags = "数据统计接口")
public class StatisticsController {

    @Autowired
    private ProductAnalyticsService productAnalyticsService;

    @Autowired
    private UserBehaviorService userBehaviorService;

    @Autowired
    private ProductCommentService productCommentService;

    @Autowired
    private MerchantStatisticsService merchantStatisticsService;

    @Autowired
    private ProductRecommendationService productRecommendationService;

    @Autowired
    private MerchantService merchantService;

    @Autowired
    private ProductService productService;

    @Autowired
    private OrderMapper orderMapper;

    // ==================== 商品分析统计 ====================

    @GetMapping("/products/analytics")
    @PreAuthorize("hasRole('ADMIN')")
    public Map<String, Object> getProductAnalytics() {
        return productAnalyticsService.getProductAnalytics(null);
    }

    @GetMapping("/products/analytics/{productId}")
    @PreAuthorize("hasRole('ADMIN')")
    public Map<String, Object> getProductAnalytics(@PathVariable Long productId) {
        return productAnalyticsService.getProductAnalytics(productId);
    }

    @GetMapping("/products/conversion/{productId}")
    @ApiOperation("获取商品转化率数据")
    @PreAuthorize("hasAnyRole('ADMIN', 'MERCHANT')")
    public ApiResponse<Map<String, Object>> getProductConversionRate(@PathVariable Long productId) {
        return ApiResponse.success(productAnalyticsService.getProductConversionRate(productId));
    }

    @GetMapping("/products/hot")
    @ApiOperation("获取热门商品排行")
    @PreAuthorize("hasAnyRole('ADMIN', 'MERCHANT')")
    public ApiResponse<Map<String, Object>> getHotProductsRanking(
            @RequestParam(defaultValue = "10") Integer limit) {
        return ApiResponse.success(productAnalyticsService.getHotProductsRanking(limit));
    }

    // ==================== 用户行为分析 ====================

    @GetMapping("/user-behavior")
    @PreAuthorize("hasRole('ADMIN')")
    public UserBehaviorStats getUserBehaviorStats() {
        // 获取所有用户的行为统计
        UserBehaviorStats totalStats = new UserBehaviorStats();
        totalStats.setTotalViews(0);
        totalStats.setTotalSearches(0);
        totalStats.setTotalPurchases(0);
        totalStats.setCategoryPreferences(new HashMap<>());
        totalStats.setTimeDistribution(new HashMap<>());
        totalStats.setDeviceDistribution(new HashMap<>());

        // 获取所有用户的行为数据并汇总
        List<com.dms.modules.user.entity.UserBehaviorStats> allStats = userBehaviorService.list();
        for (com.dms.modules.user.entity.UserBehaviorStats stats : allStats) {
            if (stats.getBehaviorType() != null) {
                switch (stats.getBehaviorType()) {
                    case "BROWSE":
                        totalStats.setTotalViews(totalStats.getTotalViews() + stats.getCount());
                        break;
                    case "SEARCH":
                        totalStats.setTotalSearches(totalStats.getTotalSearches() + stats.getCount());
                        break;
                    // 可以添加其他类型的统计
                }
            }
        }

        return totalStats;
    }

    @GetMapping("/user-behavior/{userId}")
    @PreAuthorize("hasRole('ADMIN')")
    public UserBehaviorStats getUserBehaviorStats(@PathVariable Long userId) {
        return convertToUserBehaviorStats(userBehaviorService.getBehaviorStats(userId));
    }

    @GetMapping("/user-behavior/history/{userId}")
    @ApiOperation("获取用户行为历史")
    @PreAuthorize("hasRole('ADMIN')")
    public ApiResponse<List<Map<String, Object>>> getUserBehaviorHistory(
            @PathVariable Long userId,
            @RequestParam(required = false) String behaviorType,
            @RequestParam(required = false) LocalDateTime startTime,
            @RequestParam(required = false) LocalDateTime endTime) {
        return ApiResponse.success(userBehaviorService.getUserBehaviorHistory(
                userId, behaviorType, startTime, endTime));
    }

    @GetMapping("/user-behavior/preferences/{userId}")
    @ApiOperation("获取用户分类偏好")
    @PreAuthorize("hasRole('ADMIN')")
    public ApiResponse<List<Map<String, Object>>> getUserCategoryPreferences(
            @PathVariable Long userId,
            @RequestParam(defaultValue = "5") Integer limit) {
        return ApiResponse.success(userBehaviorService.getUserCategoryPreferences(userId, limit));
    }

    @GetMapping("/user-behavior/trend/{userId}")
    @ApiOperation("获取用户行为趋势")
    @PreAuthorize("hasRole('ADMIN')")
    public ApiResponse<Map<String, Integer>> getUserBehaviorTrend(
            @PathVariable Long userId,
            @RequestParam String behaviorType,
            @RequestParam Integer days) {
        return ApiResponse.success(userBehaviorService.getBehaviorTrend(userId, 
                UserBehaviorService.BehaviorType.valueOf(behaviorType), days));
    }

    @GetMapping("/user-behavior/heatmap/{userId}")
    @ApiOperation("获取用户行为热力图")
    @PreAuthorize("hasRole('ADMIN')")
    public ApiResponse<Map<String, Map<String, Integer>>> getUserBehaviorHeatmap(
            @PathVariable Long userId,
            @RequestParam String behaviorType) {
        return ApiResponse.success(userBehaviorService.getBehaviorHeatmap(userId, 
                UserBehaviorService.BehaviorType.valueOf(behaviorType)));
    }

    // ==================== 评论统计分析 ====================

    @GetMapping("/comments/statistics")
    @PreAuthorize("hasRole('ADMIN')")
    public CommentStatisticsVO getCommentStatistics() {
        return productCommentService.getCommentStatistics(null);
    }

    @GetMapping("/comments/statistics/{productId}")
    @PreAuthorize("hasRole('ADMIN')")
    public CommentStatisticsVO getCommentStatistics(@PathVariable Long productId) {
        return productCommentService.getCommentStatistics(productId);
    }

    // ==================== 商家销售统计 ====================

    @GetMapping("/merchant/sales")
    @ApiOperation("获取商家销售统计")
    @PreAuthorize("hasAnyRole('ADMIN', 'MERCHANT')")
    public ApiResponse<Map<String, Object>> getMerchantSalesStatistics(
            @ApiParam("用户ID") @RequestParam(required = false) Long userId) {
        // 如果没有传入userId，则使用当前登录用户的ID
        if (userId == null && SecurityUtils.hasRole("MERCHANT")) {
            userId = SecurityUtils.getCurrentUserId();
        }
        return ApiResponse.success(merchantStatisticsService.getMerchantSalesStatistics(userId));
    }

    @GetMapping("/merchant/sales/my")
    @ApiOperation("获取当前商家销售统计")
    @PreAuthorize("hasRole('MERCHANT')")
    public ApiResponse<MerchantSalesStatsVO> getMyMerchantSalesStatistics() {
        // 获取当前商家ID
        Long userId = SecurityUtils.getCurrentUserId();
        Merchant merchant = merchantService.getOne(new LambdaQueryWrapper<Merchant>()
                .eq(Merchant::getUserId, userId));
        if (merchant == null) {
            throw new BusinessException("未获取到商家信息");
        }

        // 查询销售统计数据
        Map<String, Object> stats = orderMapper.getMerchantSalesStats(merchant.getId());
        
        MerchantSalesStatsVO vo = new MerchantSalesStatsVO();
        // 处理可能为null的情况
        Object totalOrdersObj = stats.get("totalOrders");
        Object totalSalesObj = stats.get("totalSales");
        Object totalRevenueObj = stats.get("totalRevenue");
        
        vo.setTotalOrders(totalOrdersObj != null ? ((Number) totalOrdersObj).longValue() : 0L);
        vo.setTotalSales(totalSalesObj != null ? ((Number) totalSalesObj).longValue() : 0L);
        vo.setTotalRevenue(totalRevenueObj != null ? (BigDecimal) totalRevenueObj : BigDecimal.ZERO);
        
        // 计算平均订单金额
        if (vo.getTotalOrders() > 0 && vo.getTotalRevenue() != null) {
            vo.setAverageOrderValue(vo.getTotalRevenue().divide(BigDecimal.valueOf(vo.getTotalOrders()), 2, RoundingMode.HALF_UP));
        } else {
            vo.setAverageOrderValue(BigDecimal.ZERO);
        }
        
        // 获取月销量
        LocalDateTime startOfMonth = LocalDateTime.now().withDayOfMonth(1).withHour(0).withMinute(0).withSecond(0);
        Map<String, Object> monthlyStats = orderMapper.getMerchantSalesStatsByDateRange(
            merchant.getId(), startOfMonth, LocalDateTime.now());
        
        // 处理月销量数据
        Object monthlySalesObj = monthlyStats.get("totalSales");
        vo.setMonthlySales(monthlySalesObj != null ? ((Number) monthlySalesObj).longValue() : 0L);

        return ApiResponse.success(vo);
    }

    @GetMapping("/merchant/orders/completion")
    @ApiOperation("获取订单完成率统计")
    @PreAuthorize("hasRole('MERCHANT')")
    public ApiResponse<Integer> getOrderCompletionRate(
            @RequestParam @ApiParam(value = "开始时间", example = "2024-01-01T00:00:00", required = true) String startTime,
            @RequestParam @ApiParam(value = "结束时间", example = "2024-12-31T23:59:59", required = true) String endTime) {
        try {
            // 获取当前商家ID
            Long userId = SecurityUtils.getCurrentUserId();
            Merchant merchant = merchantService.getOne(new LambdaQueryWrapper<Merchant>()
                    .eq(Merchant::getUserId, userId));
            if (merchant == null) {
                throw new BusinessException("未获取到商家信息");
            }

            // 解析日期时间，使用DateTimeFormatter以确保正确解析
            DateTimeFormatter formatter = DateTimeFormatter.ISO_DATE_TIME;
            LocalDateTime start;
            LocalDateTime end;
            try {
                start = LocalDateTime.parse(startTime, formatter);
                end = LocalDateTime.parse(endTime, formatter);
            } catch (DateTimeParseException e) {
                log.error("日期解析错误: startTime={}, endTime={}, error={}", startTime, endTime, e.getMessage());
                throw new BusinessException("日期格式无效，请使用正确的格式 (yyyy-MM-ddTHH:mm:ss)");
            }

            // 验证日期范围
            if (start.isAfter(end)) {
                throw new BusinessException("开始时间不能晚于结束时间");
            }

            // 获取订单完成率
            Integer completedOrders = orderMapper.countCompletedOrders(merchant.getId(), start, end);
            Integer totalOrders = orderMapper.countTotalOrders(merchant.getId(), start, end);

            // 计算完成率
            if (totalOrders == 0) {
                return ApiResponse.success(0);
            }
            
            int completionRate = (int) ((completedOrders * 100.0) / totalOrders);
            return ApiResponse.success(completionRate);
        } catch (BusinessException e) {
            throw e;
        } catch (Exception e) {
            log.error("获取订单完成率失败: error={}", e.getMessage(), e);
            throw new BusinessException("获取订单完成率失败");
        }
    }

    @GetMapping("/merchant/orders/completion/trend")
    @ApiOperation("获取订单完成率趋势")
    @PreAuthorize("hasRole('MERCHANT')")
    public ApiResponse<List<Map<String, Object>>> getOrderCompletionRateTrend(
            @RequestParam @ApiParam(value = "开始时间", example = "2024-01-01T00:00:00", required = true) String startTime,
            @RequestParam @ApiParam(value = "结束时间", example = "2024-01-31T23:59:59", required = true) String endTime) {
        try {
            // 获取当前商家ID
            Long userId = SecurityUtils.getCurrentUserId();
            Merchant merchant = merchantService.getOne(new LambdaQueryWrapper<Merchant>()
                    .eq(Merchant::getUserId, userId));
            if (merchant == null) {
                throw new BusinessException("未获取到商家信息");
            }

            // 解析日期时间
            DateTimeFormatter formatter = DateTimeFormatter.ISO_DATE_TIME;
            LocalDateTime start;
            LocalDateTime end;
            try {
                start = LocalDateTime.parse(startTime.replace("Z", ""), formatter);
                end = LocalDateTime.parse(endTime.replace("Z", ""), formatter);
            } catch (DateTimeParseException e) {
                log.error("日期解析错误: startTime={}, endTime={}, error={}", startTime, endTime, e.getMessage());
                throw new BusinessException("日期格式无效，请使用正确的格式 (yyyy-MM-ddTHH:mm:ss)");
            }

            // 验证日期范围
            if (start.isAfter(end)) {
                throw new BusinessException("开始时间不能晚于结束时间");
            }

            // 获取每日订单完成率数据
            List<Map<String, Object>> dailyData = orderMapper.getDailyOrderCompletionRate(merchant.getId(), start, end);

            // 处理数据，计算完成率百分比
            List<Map<String, Object>> result = dailyData.stream().map(data -> {
                Map<String, Object> item = new HashMap<>();
                item.put("date", data.get("date"));
                
                Long completedOrders = ((Number) data.get("completed_orders")).longValue();
                Long totalOrders = ((Number) data.get("total_orders")).longValue();
                
                // 计算完成率（百分比）
                double completionRate = totalOrders > 0 
                    ? (completedOrders * 100.0) / totalOrders 
                    : 0.0;
                
                item.put("completionRate", Math.round(completionRate * 100.0) / 100.0); // 保留两位小数
                return item;
            }).collect(Collectors.toList());

            return ApiResponse.success(result);
        } catch (BusinessException e) {
            throw e;
        } catch (Exception e) {
            log.error("获取订单完成率趋势失败: error={}", e.getMessage(), e);
            throw new BusinessException("获取订单完成率趋势失败");
        }
    }

    @GetMapping("/merchant/products/count")
    @ApiOperation("获取商家商品数量统计")
    @PreAuthorize("hasRole('MERCHANT')")
    public ApiResponse<MerchantProductStatsVO> getMerchantProductCount() {
        Long userId = SecurityUtils.getCurrentUserId();
        Merchant merchant = merchantService.getOne(new LambdaQueryWrapper<Merchant>()
                .eq(Merchant::getUserId, userId));
        if (merchant == null) {
            throw new BusinessException("未获取到商家信息");
        }

        MerchantProductStatsVO vo = new MerchantProductStatsVO();
        vo.setTotalProducts(merchantService.getProductCount(merchant.getId()));
        vo.setOnSaleProducts(productService.countByMerchantIdAndStatus(merchant.getId(), 1));
        vo.setOffSaleProducts(productService.countByMerchantIdAndStatus(merchant.getId(), 0));
        return ApiResponse.success(vo);
    }

    @GetMapping("/merchant/orders/today")
    @ApiOperation("获取商家今日订单概览")
    @PreAuthorize("hasRole('MERCHANT')")
    public ApiResponse<MerchantTodayStatsVO> getMerchantTodayOrderStats() {
        Long userId = SecurityUtils.getCurrentUserId();
        Merchant merchant = merchantService.getOne(new LambdaQueryWrapper<Merchant>()
                .eq(Merchant::getUserId, userId));
        if (merchant == null) {
            throw new BusinessException("未获取到商家信息");
        }

        LocalDateTime startTime = LocalDateTime.now().withHour(0).withMinute(0).withSecond(0);
        LocalDateTime endTime = LocalDateTime.now().withHour(23).withMinute(59).withSecond(59);

        try {
            // 获取今日订单统计数据
            MerchantTodayStatsVO vo = new MerchantTodayStatsVO();
            
            // 获取今日订单数
            Integer todayOrders = orderMapper.countTodayOrders(merchant.getId(), startTime, endTime);
            vo.setTodayOrders(todayOrders != null ? todayOrders : 0);
            
            // 获取今日销售额
            BigDecimal todayAmount = orderMapper.sumTodayAmount(merchant.getId(), startTime, endTime);
            vo.setTodayAmount(todayAmount != null ? todayAmount : BigDecimal.ZERO);
            
            // 获取待处理订单数（状态为待发货的订单）
            Integer pendingOrders = orderMapper.countPendingOrders(merchant.getId());
            vo.setPendingOrders(pendingOrders != null ? pendingOrders : 0);

            return ApiResponse.success(vo);
        } catch (Exception e) {
            log.error("获取商家今日订单概览失败: merchantId={}, error={}", merchant.getId(), e.getMessage(), e);
            throw new BusinessException("获取商家今日订单概览失败");
        }
    }

    @GetMapping("/merchant/products/hot")
    @ApiOperation("获取商家热销商品TOP5")
    @PreAuthorize("hasRole('MERCHANT')")
    public ApiResponse<List<MerchantHotProductVO>> getMerchantHotProducts() {
        Long userId = SecurityUtils.getCurrentUserId();
        Merchant merchant = merchantService.getOne(new LambdaQueryWrapper<Merchant>()
                .eq(Merchant::getUserId, userId));
        if (merchant == null) {
            throw new BusinessException("未获取到商家信息");
        }

        List<Map<String, Object>> hotProducts = orderMapper.getHotProducts(merchant.getId(), 5);
        List<MerchantHotProductVO> voList = hotProducts.stream().map(map -> {
            MerchantHotProductVO vo = new MerchantHotProductVO();
            vo.setProductId((Long) map.get("id"));
            vo.setProductName((String) map.get("name"));
            vo.setOrderCount(((Number) map.get("orderCount")).intValue());
            vo.setTotalQuantity(((Number) map.get("totalQuantity")).intValue());
            vo.setTotalAmount((BigDecimal) map.get("totalAmount"));
            return vo;
        }).collect(Collectors.toList());
        
        return ApiResponse.success(voList);
    }

    @GetMapping("/merchant/sales/trend")
    @ApiOperation("获取商家销售趋势")
    @PreAuthorize("hasRole('MERCHANT')")
    public ApiResponse<List<Map<String, Object>>> getMerchantSalesTrend(
            @RequestParam @ApiParam(value = "开始时间", example = "2024-01-01T00:00:00", required = true) String startTime,
            @RequestParam @ApiParam(value = "结束时间", example = "2024-12-31T23:59:59", required = true) String endTime,
            @RequestParam(required = false) @ApiParam(value = "统计类型：day-按天，month-按月", example = "day") String type) {
        try {
            // 获取当前商家ID
            Long userId = SecurityUtils.getCurrentUserId();
            Merchant merchant = merchantService.getOne(new LambdaQueryWrapper<Merchant>()
                    .eq(Merchant::getUserId, userId));
            if (merchant == null) {
                throw new BusinessException("未获取到商家信息");
            }

            // 解析日期时间
            DateTimeFormatter formatter = DateTimeFormatter.ISO_DATE_TIME;
            LocalDateTime start;
            LocalDateTime end;
            try {
                start = LocalDateTime.parse(startTime, formatter);
                end = LocalDateTime.parse(endTime, formatter);
            } catch (DateTimeParseException e) {
                log.error("日期解析错误: startTime={}, endTime={}, error={}", startTime, endTime, e.getMessage());
                throw new BusinessException("日期格式无效，请使用正确的格式 (yyyy-MM-ddTHH:mm:ss)");
            }

            // 验证日期范围
            if (start.isAfter(end)) {
                throw new BusinessException("开始时间不能晚于结束时间");
            }

            // 获取销售趋势数据
            List<Map<String, Object>> trendData;
            if ("month".equals(type)) {
                trendData = orderMapper.getMerchantSalesTrendByMonth(merchant.getId(), start, end);
            } else {
                trendData = orderMapper.getMerchantSalesTrendByDay(merchant.getId(), start, end);
            }

            // 处理数据，确保每个数据点都包含必要的字段
            List<Map<String, Object>> result = trendData.stream().map(data -> {
                Map<String, Object> item = new HashMap<>();
                item.put("date", data.get("date"));
                item.put("orderCount", data.get("orderCount") != null ? ((Number) data.get("orderCount")).intValue() : 0);
                item.put("salesAmount", data.get("salesAmount") != null ? (BigDecimal) data.get("salesAmount") : BigDecimal.ZERO);
                item.put("salesQuantity", data.get("salesQuantity") != null ? ((Number) data.get("salesQuantity")).intValue() : 0);
                return item;
            }).collect(Collectors.toList());

            return ApiResponse.success(result);
        } catch (BusinessException e) {
            throw e;
        } catch (Exception e) {
            log.error("获取销售趋势失败: error={}", e.getMessage(), e);
            throw new BusinessException("获取销售趋势失败");
        }
    }

    // ==================== 推荐系统分析 ====================

    @GetMapping("/recommendation/effectiveness")
    @PreAuthorize("hasRole('ADMIN')")
    public Map<String, Object> getRecommendationEffectiveness() {
        return productRecommendationService.getRecommendationMetrics(null, null);
    }

    @GetMapping("/recommendation/experiment/{experimentId}")
    @PreAuthorize("hasRole('ADMIN')")
    public Map<String, Object> getExperimentAnalysis(@PathVariable String experimentId) {
        return productRecommendationService.getRecommendationMetrics(null, experimentId);
    }

    @GetMapping("/recommendation/user-behavior/{userId}")
    @PreAuthorize("hasRole('ADMIN')")
    public Map<String, Object> getUserRecommendationBehavior(@PathVariable Long userId) {
        return productRecommendationService.getRecommendationMetrics(null, null);
    }

    /**
     * 将 entity.UserBehaviorStats 转换为 model.UserBehaviorStats
     */
    private UserBehaviorStats convertToUserBehaviorStats(com.dms.modules.user.entity.UserBehaviorStats entity) {
        if (entity == null) {
            return null;
        }
        UserBehaviorStats model = new UserBehaviorStats();
        model.setUserId(entity.getUserId());
        
        // 统计浏览次数
        if (entity.getBehaviorType() != null && entity.getBehaviorType().equals("BROWSE")) {
            model.setTotalViews(entity.getCount());
        }
        
        // 统计搜索次数
        if (entity.getBehaviorType() != null && entity.getBehaviorType().equals("SEARCH")) {
            model.setTotalSearches(entity.getCount());
        }
        
        // 获取分类偏好
        Map<String, Integer> categoryPreferences = new HashMap<>();
        if (entity.getCategoryId() != null) {
            categoryPreferences.put(entity.getCategoryId().toString(), entity.getCount());
        }
        model.setCategoryPreferences(categoryPreferences);
        
        // 获取时间分布
        Map<String, Integer> timeDistribution = new HashMap<>();
        if (entity.getCreateTime() != null) {
            String hour = String.valueOf(entity.getCreateTime().getHour());
            timeDistribution.put(hour, entity.getCount());
        }
        model.setTimeDistribution(timeDistribution);
        
        return model;
    }
} 